package com.dawn.framework.crypto.code.filter;

import com.dawn.framework.crypto.code.util.AesUtil;
import com.dawn.framework.crypto.code.wrapper.DecryptHttpServletRequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;

/**
 * @description:
 * @author: cnsu-cmh
 * @time: 2025/3/11 18:34
 */
@Slf4j
public class DecryptRequestFilter implements Filter {

    public static final String ENCRYPTED_HEADER = "x-encrypted";
    public static final String ENCRYPTED_VALUE = "true";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        if (servletRequest instanceof HttpServletRequest) {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            String encryptedHeader = request.getHeader(ENCRYPTED_HEADER);
            if (ENCRYPTED_VALUE.equals(encryptedHeader)) {
                try (BufferedReader reader = request.getReader()) {
                    // 读取原始请求体
                    String body = IOUtils.toString(reader);

                    if (body == null || body.isEmpty()) {
                        throw new IllegalArgumentException("Request body is empty");
                    }

                    // 去除前后引号
                    body = body.trim();
                    if (body.startsWith("\"") && body.endsWith("\"")) {
                        body = body.substring(1, body.length() - 1);
                    }

                    // 解密
                    String decrypted = AesUtil.decrypt(body);
                    DecryptHttpServletRequestWrapper requestWrapper = new DecryptHttpServletRequestWrapper(request,decrypted);

                    filterChain.doFilter(requestWrapper, servletResponse);
                } catch (IOException e) {
                    log.error("Failed to read request body", e);
                    throw new RuntimeException("Failed to read request body", e);
                } catch (Exception e) {
                    log.error("Decryption failed", e);
                    throw new RuntimeException("Decryption failed", e);
                }
            } else {
                filterChain.doFilter(servletRequest, servletResponse);
            }

        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }

    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
